package top.lilele.adminSystem.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket处理器
 *
 * @author lilele
 */
@Slf4j
public class WebSocketHandler extends TextWebSocketHandler {
    private static final ConcurrentHashMap<String, WebSocketSession> webSocketSessionMaps = new ConcurrentHashMap<>();

    /**
     * 开始连接
     *
     * @param session
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 获取拦截器的token
        String token = session.getAttributes().get("token").toString();
        webSocketSessionMaps.put(token, session);
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        super.handleMessage(session, message);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println("id为：" + session.getId() + "，发来：" + message);
    }

    /**
     * 关闭连接
     *
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 从集合移除
        String token = session.getAttributes().get("token").toString();
        webSocketSessionMaps.remove(token);
        log.info("退出连接～,token={}", token);
    }

    /**
     * 向指定客户端推送消息
     *
     * @param session
     * @param message
     */
    public static void sendMessage(WebSocketSession session, String message) {
        try {
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 向指定用户推送消息
     *
     * @param token
     * @param message
     */
    @SneakyThrows
    public static void sendMessage(String token, Object message) {
        ObjectMapper objectMapper = new ObjectMapper();
        String msg = objectMapper.writeValueAsString(message);
        log.error("给 {} 发送信息，信息内容 {}", token, msg);
        WebSocketSession session = webSocketSessionMaps.get(token);
        if (session != null) {
            sendMessage(session, msg);
        }
    }

    /**
     * 向多个用户发送消息
     *
     * @param message
     * @param tokens
     */
    @SneakyThrows
    public static void sendSomeUserMessage(Object message, String... tokens) {
        for (String token : tokens) {
            sendMessage(token, message);
        }
    }

    /**
     * 给所有正在连接的用户发送消息
     *
     * @param message 发送的消息
     * @param mySelf  需要排除的用户
     */
    @SneakyThrows
    public static void sendEveryUserMessage(Object message, String... mySelf) {
        webSocketSessionMaps.forEach((key, value) -> {
            if (!Arrays.asList(mySelf).contains(key)) {
                sendMessage(key, message);
            }
        });
    }

    /**
     * 获取当前在线map信息
     *
     * @return
     */
    public static ConcurrentHashMap<String, WebSocketSession> getOnLineUserList() {
        return webSocketSessionMaps;
    }
}
